package com.dj.product.k2faas.common.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import com.fasterxml.jackson.databind.type.SimpleType;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.dj.product.k2faas.common.exception.K2Exception;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by 丁建 on 2025/9/23 08:40
 *
 * @author 丁建
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class JsonUtil {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 对象没有属性时，也要序列化
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

    public static Object toObject(String json, String className) {
        try {
            SimpleType javaType = SimpleType.constructUnsafe(Class.forName(className));
            return objectMapper.readValue(json, javaType);
        } catch (Exception e) {
            log.error("将字符串：{}转为对象：{}时出错。", json, className);
            throw new K2Exception(e);
        }
    }

    public static <T> T toObject(String json, TypeReference<T> typeReference) {
        Assert.hasLength(json, "要转对象的JSON字符串不能为空。");
        try {
            return objectMapper.readValue(json, typeReference);
        } catch (IOException e) {
            log.error("将字符串：{}转为对象：{}时出错。", json, typeReference);
            throw new K2Exception(e);
        }
    }

    public static <T> T toObject(String json, Class<T> clazz) {
        Assert.hasLength(json, "要转对象的JSON字符串不能为空。");
        try {
            return objectMapper.readValue(json, clazz);
        } catch (IOException e) {
            log.error("将字符串：{}转为对象：{}时出错。", json, clazz);
            throw new K2Exception(e);
        }
    }

    public static String toJSON(Object object) {
        return toJSON(object, false);
    }

    /**
     * 转换为人读友好的Json格式
     */
    public static String toJSON(Object object, boolean readable) {
        Assert.notNull(object, "要转JSON的对像不能为空。");

        try {
            if (readable) {
                return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
            } else {
                return objectMapper.writeValueAsString(object);
            }
        } catch (Exception e) {
            log.error("将对象：{}转为JSON字符串时出错。", object);
            throw new K2Exception(e);
        }
    }

    public static <T> List<T> toList(String json, Class<T> elementClass) {
        CollectionLikeType type = objectMapper.getTypeFactory().constructCollectionLikeType(ArrayList.class, elementClass);
        try {
            return objectMapper.readValue(json, type);
        } catch (Exception e) {
            log.error("将JSON:{}转为List<{}>时出错。", json, elementClass);
            throw new K2Exception(e);
        }
    }

    public static <T> T toObject(Map<String, Object> map, Class<T> clazz) {
        Assert.notNull(map, "要转对象的map不能为空。");
        return objectMapper.convertValue(map, clazz);
    }

    public static Map<String, Object> toMap(Object object) {
        Assert.notNull(object, "要转map的对象不能为空。");
        return objectMapper.convertValue(object, new TypeReference<>() {
        });
    }

    public static ObjectMapper getObjectMapper() {
        return objectMapper;
    }
}
